import { getImageUrl } from '@/utils/tool'
import { ref, onBeforeUnmount } from 'vue'
import AMapLoader from '@amap/amap-jsapi-loader'

export function useAMap(
  containerId,
  center = [113.429126, 23.165105],
  zoom = 8,
) {
  const map = ref(null)
  const markers = ref([])
  const infoWindow = ref(null)

  const initMap = () => {
    return AMapLoader.load({
      key: '5f4cc2c20a6d4fa9a738af2f8ffc9996', // 申请好的Web端开发者Key，首次调用 load 时必填
      version: '1.4.15', //默认版本为 1.4.15 // 2.0版本会和 mockjs冲突
      plugins: [], // 需要使用的插件列表，如比例尺'AMap.Scale'等
    })
      .then((AMap) => {
        map.value = new AMap.Map(containerId, {
          viewMode: '3D', // 是否为3D地图模式
          zoom, // 初始化地图级别
          center, // 初始化地图中心点位置
          // mapStyle: 'amap://styles/blue' // 切换主题
        })
      })
      .catch((e) => {
        console.error(e)
      })
  }

  // 设置中心点
  const changeCenter = (center = [120.732365, 37.944057]) => {
    if (!map.value) {
      return
    }
    map.value.setCenter(center)
  }

  // 设置层级
  const setZoom = (zoom = 12.8) => {
    if (!map.value) {
      return
    }
    map.value.setZoom(zoom)
  }

  // 限制展示范围
  const setLimitBounds = (
    southWest = [116.0119343, 39.66127144],
    northEast = [116.7829835, 40.2164962],
  ) => {
    if (!map.value) {
      return
    }
    let sw = new AMap.LngLat(southWest[0], southWest[1])
    let ne = new AMap.LngLat(northEast[0], northEast[1])
    map.value.setLimitBounds(new AMap.Bounds(sw, ne))
  }

  // 设置区域范围
  const addHandDrawnLayer = (path) => {
    if (!map.value) {
      return
    }
    const polygon = new AMap.Polygon({
      path, // 手绘图的路径
      strokeOpacity: 1,
      fillOpacity: 0,
      strokeColor: '#0484F2',
      strokeWeight: 5,
      borderWeight: 10,
      strokeStyle: 'dashed',
      strokeDasharray: [20, 10],
      zIndex: 50,
    })
    map.value.add(polygon)
  }

  // 加载手绘地图
  const addImageLayer = (
    bounds = [
      [120.64542063, 37.87530803], // 左下 手绘图左下相对于地图的经纬度
      [120.8024979, 38.0018083], // 右上
    ],
    zIndex = 100,
    zooms = [12, 20],
  ) => {
    if (!map.value) {
      return
    }
    const imageLayer = new AMap.ImageLayer({
      bounds: new AMap.Bounds(bounds[0], bounds[1]),
      url: getImageUrl('gzip-iot.png'),
      zIndex,
      zooms,
    })

    map.value.add(imageLayer)
  }

  // 添加点标记
  const addMarkers = (points, eventHandler) => {
    if (!map.value) {
      return
    }
    points.forEach((point) => {
      const marker = new AMap.Marker({
        position: [point.longitude, point.latitude],
        anchor: 'bottom-center',
        title: point.title,
        icon: new AMap.Icon({
          size: new AMap.Size(32, 33), // 图标大小
          image: getImageUrl(point.icon),
          imageSize: new AMap.Size(32, 33), // 图标大小
        }),
      })
      marker.on('click', () => eventHandler(point))
      map.value.add(marker)
      markers.value.push(marker)
    })
  }

  /**
   * 移除点标记
   * @param {Array<Number>} indexs - 点数组下标
   */
  const removeMarkers = (indexs = []) => {
    // 删除全部点标记
    if (!indexs.length) {
      map.value.remove(markers.value)
      markers.value = []
      return
    }
    // 删除部分点标记
    indexs.forEach((i) => {
      markers.value[i].setMap(null)
    })
  }

  // 创建信息窗体
  const createInfoWindow = (content, position) => {
    if (!map.value) {
      return
    }
    if (infoWindow.value) {
      removeInfoWindow()
    }
    infoWindow.value = new AMap.InfoWindow({
      isCustom: true,
      content: content,
      anchor: 'bottom-center',
      offset: new AMap.Pixel(0, -40),
    })
    infoWindow.value.open(map.value, position)
  }

  // 注销信息窗体
  const removeInfoWindow = () => {
    if (infoWindow.value) {
      infoWindow.value.close()
      infoWindow.value = null
    }
  }
  // 清理地图实例
  onBeforeUnmount(() => {
    if (map.value) {
      map.value.destroy()
      map.value = null
    }
  })

  return {
    map,
    initMap,
    addHandDrawnLayer,
    addImageLayer,
    addMarkers,
    removeMarkers,
    createInfoWindow,
    removeInfoWindow,
    changeCenter,
    setZoom,
    setLimitBounds,
  }
}
